package cn.supermay.tool;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

import cn.supermay.tool.code.CodeGen;
import cn.supermay.tool.swing.BaseFrame;
import cn.supermay.tool.swing.Images;
import cn.supermay.tool.swing.Loading;

public class MainFrame extends BaseFrame {
	private static final long serialVersionUID = -6541864654653129335L;
	
	private static final int __WITDH__ = 1200;
	private static final int __HEIGHT__ = 480;
	
	static MainFrame frame;
	
	private JPanel titlePanel = new JPanel();
	private JPanel commonPanel = new JPanel();
	private JPanel infoPanel = new JPanel();
	private JPanel buttonPanel = new JPanel();
	
	private JTextField text_packageName;
	private JTextField text_modelName;
	
	private JCheckBox checkBox_entity;
	private JTextField text_entityClassName;
	private JTextField text_entityPackageName;
	private JTextField text_entityTableName;

	private JCheckBox checkBox_repository;
	private JTextField text_repositoryClassName;
	private JTextField text_repositoryPackageName;
	
	private JCheckBox checkBox_service;
	private JTextField text_serviceClassName;
	private JTextField text_servicePackageName;
	private JTextField text_serviceImplClassName;
	
	private JCheckBox checkBox_controller;
	private JTextField text_controllerClassName;
	private JTextField text_controllerPackageName;
	private JTextField text_controllerRootUri;

	private JCheckBox checkBox_bean;
	private JTextField text_beanClassName;
	private JTextField text_beanPackageName;
	
	public static void main(String[] args) {
		Loading loading = Loading.getLoading();
		loading.open();

		try {
			beforeShowup();
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			loading.close();
		}
	}
	
	public static void beforeShowup() throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException {
		UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		
		frame= new MainFrame();
		init();
		SwingUtilities.updateComponentTreeUI(frame);
	}
 
	public static void init() {
		frame.setType(Type.UTILITY);
		frame.setAlwaysOnTop(true);
		frame.setAutoRequestFocus(false);
		frame.setResizable(false);
		frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Images.getImage("logo.png")));
		
		// Title label
		frame.__init_title__();
		frame.__make_panels__();
		
		// Controls action
		frame.__init_actions__();

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
		frame.setSize(__WITDH__, __HEIGHT__);
		frame.setResizable(true);
		frame.setLocationRelativeTo(null);
	}

	private void __init_actions__() {
		checkBox_entity.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {

            	boolean enable = checkBox_entity.isSelected();

            	text_entityClassName.setEditable(enable);
            	text_entityPackageName.setEditable(enable);
            	text_entityTableName.setEditable(enable);

            }
        });
		
		checkBox_repository.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
            	boolean enable = checkBox_repository.isSelected();
            	text_repositoryClassName.setEditable(enable);
            	text_repositoryPackageName.setEditable(enable);
            }
        });

		checkBox_service.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
            	boolean enable = checkBox_service.isSelected();
            	text_serviceClassName.setEditable(enable);
            	text_servicePackageName.setEditable(enable);
            	text_serviceImplClassName.setEditable(enable);
            }
        });

		checkBox_controller.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
            	boolean enable = checkBox_controller.isSelected();
            	text_controllerClassName.setEditable(enable);
            	text_controllerPackageName.setEditable(enable);
            	text_controllerRootUri.setEditable(enable);
            }
        });

		checkBox_bean.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
            	boolean enable = checkBox_bean.isSelected();
            	text_beanClassName.setEditable(enable);
            	text_beanPackageName.setEditable(enable);
            }
        });
		
		text_packageName.addKeyListener(new KeyListener() {

			@Override
			public void keyPressed(KeyEvent arg0) {}

			@Override
			public void keyReleased(KeyEvent arg0) {}

			@Override
			public void keyTyped(KeyEvent arg0) {
				if (KeyEvent.VK_ENTER == arg0.getKeyChar()) {

					String packageName = text_packageName.getText().trim();
					
					if (packageName.isEmpty())
						return;
					
					text_entityPackageName.setText(packageName + ".entity");
					text_repositoryPackageName.setText(packageName + ".repository");
					text_servicePackageName.setText(packageName + ".service");
					text_controllerPackageName.setText(packageName + ".controller");
					text_beanPackageName.setText(packageName + ".bean");
				}
			}
		});
		
		text_modelName.addKeyListener(new KeyListener() {

			@Override
			public void keyPressed(KeyEvent arg0) {}

			@Override
			public void keyReleased(KeyEvent arg0) {}

			@Override
			public void keyTyped(KeyEvent arg0) {
				if (KeyEvent.VK_ENTER == arg0.getKeyChar()) {

					String modelName = text_modelName.getText().trim();
					
					if (modelName.isEmpty())
						return;
					
					text_entityClassName.setText(modelName+"Entity");
					text_repositoryClassName.setText(modelName+"Repository");
					text_serviceClassName.setText("I"+modelName+"Service");
					text_serviceImplClassName.setText(modelName+"ServiceImpl");
					text_controllerClassName.setText(modelName+"Controller");
					text_beanClassName.setText(modelName+"Bean");

					text_entityTableName.setText("tb_" + modelName.toLowerCase());
					text_controllerRootUri.setText("/" + modelName.toLowerCase());
				}
				
			}
			
		});
	}

	private JPanel __init_buttons__() {
		final JButton jb1 = new JButton("确认");
		final JButton jb2 = new JButton("退出");
		jb2.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent event) {
				System.exit(0);
			}
		});
		
		jb1.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent event) {
				CodeGen gen = new CodeGen();
				
			    JFileChooser fd = new JFileChooser();
			    fd.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
			    // fd.showOpenDialog(null);
			    int answer = fd.showSaveDialog(frame);
			    if (answer != JFileChooser.APPROVE_OPTION) {
			    	return;
			    }
			    
			    File f = fd.getSelectedFile();
			    
				gen.setRootDir(f.getAbsolutePath());
				gen.setNamings(
						text_entityClassName.getText().trim(), // entity,
						text_entityTableName.getText().trim(), // table,
						text_repositoryClassName.getText().trim(), // repository,
						text_serviceClassName.getText().trim(), // service,
						text_serviceImplClassName.getText().trim(), // serviceImpl,
						text_controllerClassName.getText().trim(), // controller,
						text_controllerRootUri.getText().trim(), // controllerUri
						text_beanClassName.getText().trim()); // bean

				try {
					if (checkBox_entity.isSelected()) {
							gen.genEntityFile(text_entityPackageName.getText().trim());
					}
					if (checkBox_repository.isSelected()) {
						gen.genRepositoryFile(text_repositoryPackageName.getText().trim());
					}
					if (checkBox_service.isSelected()) {
						gen.genServiceFile(text_servicePackageName.getText().trim());
						gen.genServiceImplFile(text_servicePackageName.getText().trim());
					}
					if (checkBox_controller.isSelected()) {
						gen.genControllerFile(text_controllerPackageName.getText().trim());
					}
					if (checkBox_bean.isSelected()) {
						gen.genBeanFile(text_beanPackageName.getText().trim());
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					JOptionPane.showMessageDialog( frame, 
							e.getMessage(),
							"生成代码失败" ,
							JOptionPane.ERROR_MESSAGE) ;
					
					return;
				}
				
				JOptionPane.showMessageDialog(frame, "完成");
			}
		});

		buttonPanel = new JPanel();
		buttonPanel.add(jb1);
		buttonPanel.add(jb2);
		buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		
		return buttonPanel;
	}

	private void __make_panels__() {

		titlePanel = __init_title__();

        commonPanel = __init_common__();
        infoPanel = __init_info__();
        buttonPanel = __init_buttons__();

		JPanel contentPane=new JPanel();
        contentPane.setBorder(new EmptyBorder(5,5,5,5));
        contentPane.setLayout(new BorderLayout(5, 5));
        contentPane.add(titlePanel, BorderLayout.NORTH);
		JPanel centerPanel=new JPanel();
		centerPanel.setLayout(new BorderLayout(5, 5));
		centerPanel.add(commonPanel, BorderLayout.NORTH);
		centerPanel.add(infoPanel, BorderLayout.CENTER);
        contentPane.add(centerPanel, BorderLayout.CENTER);
        contentPane.add(buttonPanel, BorderLayout.SOUTH);
        
        frame.setContentPane(contentPane);
        
		this.setTitle("Spring-Boot 代码生成器");
	}
	
	private void addToPanel(JPanel panel, JComponent comp, GridBagLayout gridbag, GridBagConstraints c, int iCol) {
		c.gridx = iCol;
		gridbag.setConstraints(comp, c);
		panel.add(comp);
	}

	private JPanel __init_info__() {
		infoPanel = new JPanel();
		GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        
        infoPanel.setLayout(gridbag);
        
        c.fill = GridBagConstraints.BOTH;
		c.insets = new Insets(5, 5, 5, 5);
        c.weightx = 1.0;
        c.gridwidth = 1;
        c.gridheight = 1;

		// 1. DTO
		checkBox_entity = new JCheckBox("entity", true);
		text_entityClassName = new JTextField("class");
		text_entityPackageName = new JTextField("package");
		text_entityTableName = new JTextField("tb_user");

		c.gridwidth = 1;
		c.weightx = 1.0;
		addToPanel(infoPanel, checkBox_entity, gridbag, c, 0);
		c.weightx = 2.0;
		c.gridwidth = 2;
		addToPanel(infoPanel, text_entityClassName, gridbag, c, 1);
		addToPanel(infoPanel, text_entityPackageName, gridbag, c, 3);
		addToPanel(infoPanel, text_entityTableName, gridbag, c, 5);
		
		// 2. Repository
		checkBox_repository = new JCheckBox("repository", true);
		text_repositoryClassName = new JTextField("repository class");
		text_repositoryPackageName = new JTextField("repository package");

		c.gridwidth = 1;
		c.weightx = 1.0;
		addToPanel(infoPanel, checkBox_repository, gridbag, c, 0);
		c.gridwidth = 2;
		c.weightx = 2.0;
		addToPanel(infoPanel, text_repositoryClassName, gridbag, c, 1);
		c.gridwidth = GridBagConstraints.EAST;
		addToPanel(infoPanel, text_repositoryPackageName, gridbag, c, 3);
		
		// 3. Service
		checkBox_service = new JCheckBox("service", true);
		text_serviceClassName = new JTextField("service class");
		text_servicePackageName = new JTextField("service package");
		text_serviceImplClassName = new JTextField("service implement class");

		c.gridwidth = 1;
		c.weightx = 1.0;
		addToPanel(infoPanel, checkBox_service, gridbag, c, 0);
		c.gridwidth = 2;
		c.weightx = 2.0;
		addToPanel(infoPanel, text_serviceClassName, gridbag, c, 1);
		addToPanel(infoPanel, text_servicePackageName, gridbag, c, 3);
		addToPanel(infoPanel, text_serviceImplClassName, gridbag, c, 5);

		// 4. Controller
		checkBox_controller = new JCheckBox("controller", true);
		text_controllerClassName = new JTextField("controller class");
		text_controllerPackageName = new JTextField("controller package");
		text_controllerRootUri = new JTextField("/controlleruri");

		c.gridwidth = 1;
		c.weightx = 1.0;
		addToPanel(infoPanel, checkBox_controller, gridbag, c, 0);
		c.gridwidth = 2;
		c.weightx = 2.0;
		addToPanel(infoPanel, text_controllerClassName, gridbag, c, 1);
		addToPanel(infoPanel, text_controllerPackageName, gridbag, c, 3);
		addToPanel(infoPanel, text_controllerRootUri, gridbag, c, 5);
		

		// 5. Bean
		checkBox_bean = new JCheckBox("bean", true);
		text_beanClassName = new JTextField("bean class");
		text_beanPackageName = new JTextField("bean package");

		c.gridwidth = 1;
		c.weightx = 1.0;
		addToPanel(infoPanel, checkBox_bean, gridbag, c, 0);
		c.gridwidth = 2;
		c.weightx = 2.0;
		addToPanel(infoPanel, text_beanClassName, gridbag, c, 1);
		c.gridwidth = GridBagConstraints.EAST;
		addToPanel(infoPanel, text_beanPackageName, gridbag, c, 3);
		
		infoPanel.setBorder(BorderFactory.createDashedBorder(Color.GRAY));
		return infoPanel;
	}

	private JPanel __init_title__() {

        titlePanel = new JPanel();
        
		JLabel jl = new JLabel("Spring-Boot 代码生成器", SwingUtilities.CENTER);
		Font font = new Font("宋体", Font.BOLD, 24);
		jl.setFont(font);
		titlePanel.add(jl);
		
		titlePanel.setBorder(BorderFactory.createEmptyBorder());
		
		return titlePanel;
	}

	private JPanel __init_common__() {
        
		commonPanel = new JPanel();
		
		GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        
        commonPanel.setLayout(gridbag);
		
		JLabel label_a = new JLabel("根包名", SwingUtilities.RIGHT);
		JLabel label_b = new JLabel("实体名", SwingUtilities.RIGHT);
		text_packageName = new JTextField("cn.supermay.api.modules", SwingUtilities.LEFT);
		text_modelName = new JTextField("User", SwingUtilities.LEFT);

		c.insets = new Insets(10, 10, 10, 10);

        c.weightx = 1.0;
        c.gridwidth = 1;
        c.fill = GridBagConstraints.HORIZONTAL;
        addToPanel(commonPanel, label_a, gridbag, c, 0);
        c.fill = GridBagConstraints.BOTH;
        c.weightx = 3.0;
        c.gridwidth = 3;
        addToPanel(commonPanel, text_packageName, gridbag, c, 1);

        c.weightx = 1.0;
        c.gridwidth = 1;
        addToPanel(commonPanel, label_b, gridbag, c, 4);
        c.fill = GridBagConstraints.BOTH;
        c.weightx = 3.0;
        c.gridwidth = 3;
        addToPanel(commonPanel, text_modelName, gridbag, c, 5);

        commonPanel.setBorder(BorderFactory.createDashedBorder(Color.GRAY));
		return commonPanel;
	}
	

}
